﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace Common.IO
{

    public delegate void delegateProcess(string blockText);
    public class BigTextFile
    {
        void ProcessText(string blockText)
        {
            var index = 0;
            var pattern = "xxxxxxx";
            while ((index = Common.Algo.KMP.Execute(blockText, pattern, index)) > 0)
            {
                Console.WriteLine("finded at " + index);
                Console.WriteLine("line:" + ReadLineBlock(blockText, index));
                index += pattern.Length;
            }
        }

        string ReadLineBlock(string source, int index)
        {
            if (index < 0 || index >= source.Length)
            {
                return "";
            }
            StringBuilder sb = new StringBuilder();
            while (true)
            {
                if (index < 0) { break; }
                if (source[index] == '\n')
                {
                    break;
                }
                index--;
            }
            index++;
            while (true)
            {
                if (index >= source.Length) { break; }
                if (source[index] == '\n')
                {
                    break;
                }
                sb.Append(source[index]);
                index++;
            }
            return sb.ToString();

        }
        public void ReadBigTextFile(string filePath, delegateProcess _delegateProcess)
        {
            ReadBigTextFile(filePath, Encoding.Default, _delegateProcess);
        }
        public void ReadBigTextFile(string filePath, Encoding encode, delegateProcess _delegateProcess)
        {
            var blockLength = 10 * 1024 * 1024;
            ReadBigTextFile(filePath, encode, _delegateProcess, blockLength);
        }
        /// <summary>
        /// 读取大文本文件
        /// </summary>
        /// <param name="filePath">文件名</param>
        /// <param name="_delegateProcess">处理文本块的委托</param>
        /// <param name="blockLength">定义一个文本块的长度</param>
        public void ReadBigTextFile(string filePath, Encoding encode, delegateProcess _delegateProcess, int blockLength)
        {
            var minBlockLength = 10 * 1024 * 1024;    //20MB
            var maxBlockLength = 100 * 1024 * 1024;  //200MB

            if (blockLength > maxBlockLength)
            {
                blockLength = maxBlockLength;
            }
            else if (blockLength < minBlockLength)
            {
                blockLength = minBlockLength;
            }

            var sbBlockText = new StringBuilder(blockLength);
            if (!string.IsNullOrEmpty(filePath)
                && File.Exists(filePath))
            {
                using (StreamReader sr = new StreamReader(filePath, encode))
                {
                    char[] buffer = new char[10 * 1024];
                    var index = 0;
                    var fileLength = sr.BaseStream.Length;
                    var readedLength = 0;
                    while ((index = sr.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        if (readedLength >= blockLength)
                        {
                            if (_delegateProcess != null)
                            {
                                _delegateProcess(sbBlockText.ToString());
                            }
                            sbBlockText.Remove(0, sbBlockText.Length);
                            readedLength = 0;
                        }
                        sbBlockText.Append(buffer, 0, index);
                        readedLength += index;
                    }
                    if (_delegateProcess != null)
                    {
                        _delegateProcess(sbBlockText.ToString());
                    }
                }
            }
        }
    }
}
